package com.pig4cloud.pigx.contract.controller;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.map.MapUtil;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.customize.api.enums.AbnormalEnum;
import com.pig4cloud.pigx.common.customize.api.exception.OpenApiException;
import com.pig4cloud.pigx.common.customize.api.interceptor.OpenApiValidator;
import com.pig4cloud.pigx.common.customize.api.util.OpenApiUtil;
import com.pig4cloud.pigx.common.customize.exception.MqAckException;
import com.pig4cloud.pigx.common.customize.i18n.util.MessageUtils;
import com.pig4cloud.pigx.common.customize.utils.CommonUtil;
import com.pig4cloud.pigx.contract.constant.I18nMessages;
import com.pig4cloud.pigx.contract.dto.ContractPositionLiquidateEmailDTO;
import com.pig4cloud.pigx.contract.dto.ContractPositionNeedAppendMarginEmailDTO;
import com.pig4cloud.pigx.contract.executer.position.PositionExecutor;
import com.pig4cloud.pigx.contract.service.TestService;
import com.pig4cloud.pigx.contract.utils.ContractEmailSender;
import com.pig4cloud.pigx.user.entity.User;
import com.pig4cloud.pigx.wallet.entity.ContractAccount;
import lombok.AllArgsConstructor;
import org.apache.logging.log4j.util.Strings;
import org.springframework.http.HttpMethod;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * @date 2022/8/29 16:54
 */
@RestController
@RequestMapping("/test")
@AllArgsConstructor
public class TestController {

    private final PositionExecutor positionExecutor;
    private final ContractEmailSender contractEmailSender;
    private final CommonUtil commonUtil;

    private final TestService testService;

    /**
     * 计算全仓强平价-liquidatePriceFull
     */
    @PostMapping("/liquidate-price-full")
    public void liquidatePriceFull() {
        throw new RuntimeException(MessageUtils.get(I18nMessages.ABNORMAL_OPERATION));
        // positionExecutor.liquidatePriceFull(CommonUtil.getLoginUser().getId().toString());
    }

    /**
     * 修改合约账户
     */
    @PostMapping("/change-contract-account")
    public void changeContractAccount(String operationType) {
        testService.changeAsset(operationType);
    }

    /**
     * 合约账户查询
     *
     * @param userId 用户id
     * @return {@link R< ContractAccount>}
     * @since 2022/9/22 10:20
     */
    @GetMapping("/account-info")
    public R<ContractAccount> accountInfo(Long userId) {
        ContractAccount account = testService.accountInfo(userId);

        return R.ok(account);
    }

    /**
     * 合约账户查询并锁定
     *
     * @param userId 用户id
     * @return {@link R< ContractAccount>}
     * @since 2022/9/22 10:20
     */
    @GetMapping("/account-info/lock")
    public R<ContractAccount> accountInfoLock(Long userId) {
        ContractAccount account = testService.accountInfoLock(userId);

        return R.ok(account);
    }

    /**
     * 发送强平邮件
     *
     * @since 2022/9/16 10:17
     */
    @GetMapping("/send-email/liquidate")
    public void sendEmailLiquidate() {
        // 发送邮件
        try {
            ContractPositionLiquidateEmailDTO dto = new ContractPositionLiquidateEmailDTO();
            dto.setUserId(2L);
            dto.setSymbolName("ABC");
            dto.setPositionMode("0");
            dto.setSide("0");
            dto.setMultiple(10);
            dto.setMarkPrice(BigDecimal.valueOf(20000));

            User user = new User();
            user.setEmail("1036532868@qq.com");
            user.setLanguageCode("zh_CN");
            contractEmailSender.sendLiquidate(dto, user);
            user.setLanguageCode("zh_TW");
            contractEmailSender.sendLiquidate(dto, user);
            user.setLanguageCode("en_US");
            contractEmailSender.sendLiquidate(dto, user);
        } catch (
                MessagingException e) {
            throw new MqAckException(e);
        }
    }

    /**
     * 发送强平邮件
     *
     * @since 2022/9/16 10:17
     */
    @GetMapping("/send-email/need-append-margin")
    public void sendEmailNeedAppendMargin() {
        // 发送邮件
        try {
            ContractPositionNeedAppendMarginEmailDTO emailDto = new ContractPositionNeedAppendMarginEmailDTO();
            emailDto.setUserId(2L);
            emailDto.setSymbolName("ABC");
            emailDto.setPositionMode("0");
            emailDto.setSide("0");
            emailDto.setMultiple(10);

            User user = new User();
            user.setEmail("1036532868@qq.com");
            user.setLanguageCode("zh_CN");
            contractEmailSender.sendNeedAppendMargin(emailDto, user);
            user.setLanguageCode("zh_TW");
            contractEmailSender.sendNeedAppendMargin(emailDto, user);
            user.setLanguageCode("en_US");
            contractEmailSender.sendNeedAppendMargin(emailDto, user);
        } catch (
                MessagingException e) {
            throw new MqAckException(e);
        }
    }

    /**
     * 根据请求参数生成签名
     *
     * @param request  请求包
     * @param response 响应包
     * @return {@link R< String>}
     * @since 2023/1/9 20:22
     */
    @RequestMapping("/signature")
    public R<String> signature(HttpServletRequest request, HttpServletResponse response) {
        // 将所有参数按照参数名升序排序
        TreeMap<String, Object> treeMap = new TreeMap<>(Comparator.naturalOrder());
        // 获取queryString中的参数
        Map<String, String[]> queryMap = request.getParameterMap();
        // 获取签名并从参数集合中移除
        String signature = OpenApiValidator.getSignature(queryMap);

        String secretKey = CommonUtil.getParamString(queryMap, "secretKey", false);
        System.err.println(secretKey);
        if (Strings.isBlank(secretKey)) {
            secretKey = "";
        }

        treeMap.putAll(queryMap);

        try {
            // 如果是POST请求，将请求体中的参数也加入到排序
            if (HttpMethod.POST.matches(request.getMethod())) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
                String read = IoUtil.read(reader, false);

                Map bodyMap = commonUtil.parseJson(read, HashMap.class);
                treeMap.putAll(bodyMap);
            }

            // 不可能没有参数，存在诸如tiemstamp、nonce等必传参数
            if (MapUtil.isEmpty(queryMap)) {
                OpenApiUtil.throwError(AbnormalEnum.MSG.INVALID_SIGNATURE);
            }

            // 转换为json
            String json = commonUtil.toJson(treeMap);

            // 加密
            String jsonSignature = OpenApiValidator.signature(secretKey, json);
            return R.ok(jsonSignature);

        } catch (OpenApiException e) {
            throw e;
        } catch (Exception e) {
            OpenApiUtil.throwError(AbnormalEnum.MSG.DISCONNECTED);
        }

        return R.failed();
    }
}
